package czk.concrent.waitandnotify;

/**
 * @Author:ChenZhangKun
 * @Date: 2020/5/24 10:47
 */

/**
 * wait notify正确使用方式
 */
public class Test2 {
    static final Object object=new Object();
    static boolean hasMoney=false;
    static boolean hasTakeout=false;
    public static void main(String[] args) throws InterruptedException {

        // 线程一
        new Thread(()->{
            // 是否有钱
            synchronized (object){
                // 防止虚假唤醒
                while (!hasMoney){
                    System.out.println(Thread.currentThread().getName()+"没钱需要等待");
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 有钱了
                if (hasMoney){
                    System.out.println(Thread.currentThread().getName()+"有钱了。买东西");
                }else {
                    System.out.println(Thread.currentThread().getName()+"没干成活");
                }
            }

        },"陈彰坤").start();
        new Thread(()->{
            // 是否有钱
            synchronized (object){
                //循环检测是否被唤醒
                while (!hasTakeout){
                    System.out.println(Thread.currentThread().getName()+"没外卖需要等待");
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 有钱了
                if (hasTakeout){
                    System.out.println(Thread.currentThread().getName()+"有外卖了，吃东西");
                }else {
                    System.out.println(Thread.currentThread().getName()+"没吃成");
                }
            }

        },"宁中琼").start();
        Thread.sleep(1);
        // 其他线程干活
        Thread.currentThread().setName("主线程");
        for (int i = 0; i <5 ; i++) {
            synchronized (object){
                System.out.println(Thread.currentThread().getName()+"干活了");
            }
        }
        Thread.sleep(1*100);
        // 送钱的
        new Thread(()->{
            synchronized (object){
                hasMoney=true;
                System.out.println(Thread.currentThread().getName()+"送钱来了");
                // 全部唤醒
                object.notifyAll();
                // 随机唤醒，可能唤醒送外卖的
                //object.notify();
            }
        },"送钱的").start();
        // 送外卖的
        new Thread(()->{
            synchronized (object){
                hasTakeout=true;
                System.out.println(Thread.currentThread().getName()+"送外卖的来了");
                // 随机唤醒 可能唤醒送钱的
                //object.notify();
                // 全部唤醒
                object.notifyAll();
            }
        },"送外卖的").start();
    }
}
